home *** CD-ROM | disk | FTP | other *** search
/ Freelog 125 / Freelog_MarsAvril2015_No125.iso / Musique / Quod Libet / quodlibet-3.3.0-portable.exe / quodlibet-3.3.0-portable / data / bin / quodlibet / qltk / songsmenu.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2014-12-31  |  12KB  |  377 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.7)
  3.  
  4. from gi.repository import Gtk
  5. from quodlibet import qltk
  6. from quodlibet.util import print_exc
  7. from quodlibet.qltk.msg import WarningMessage
  8. from quodlibet.qltk.delete import TrashMenuItem, trash_songs
  9. from quodlibet.qltk.information import Information
  10. from quodlibet.qltk.properties import SongProperties
  11. from quodlibet.qltk.x import SeparatorMenuItem, Button
  12. from quodlibet.qltk import get_top_parent
  13. from quodlibet.util import connect_obj
  14. from quodlibet.plugins import PluginManager, PluginHandler
  15. from quodlibet.plugins.songsmenu import SongsMenuPlugin
  16. from quodlibet.util.songwrapper import ListWrapper, check_wrapper_changed
  17.  
  18. class ConfirmMultiSongInvoke(WarningMessage):
  19.     '''Dialog to confirm invoking a plugin with X songs in case X is high'''
  20.     RESPONSE_INVOKE = 1
  21.     
  22.     def __init__(self, parent, plugin_name, count):
  23.         title = ngettext('Run the plugin "%s" on %d song?', 'Run the plugin "%s" on %d songs?', count) % (plugin_name, count)
  24.         super(ConfirmMultiSongInvoke, self).__init__(get_top_parent(parent), title, '', buttons = Gtk.ButtonsType.NONE)
  25.         self.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
  26.         delete_button = Button(_('_Run Plugin'), Gtk.STOCK_EXECUTE)
  27.         delete_button.show()
  28.         self.add_action_widget(delete_button, self.RESPONSE_INVOKE)
  29.         self.set_default_response(Gtk.ResponseType.CANCEL)
  30.  
  31.     
  32.     def confirm(cls, parent, plugin_name, count):
  33.         '''Returns if the action was confirmed'''
  34.         resp = cls(parent, plugin_name, count).run()
  35.         return resp == cls.RESPONSE_INVOKE
  36.  
  37.     confirm = classmethod(confirm)
  38.  
  39.  
  40. class ConfirmMultiAlbumInvoke(WarningMessage):
  41.     '''Dialog to confirm invoking a plugin with X albums in case X is high'''
  42.     RESPONSE_INVOKE = 1
  43.     
  44.     def __init__(self, parent, plugin_name, count):
  45.         title = ngettext('Run the plugin "%s" on %d album?', 'Run the plugin "%s" on %d albums?', count) % (plugin_name, count)
  46.         super(ConfirmMultiAlbumInvoke, self).__init__(get_top_parent(parent), title, '', buttons = Gtk.ButtonsType.NONE)
  47.         self.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
  48.         delete_button = Button(_('_Run Plugin'), Gtk.STOCK_EXECUTE)
  49.         delete_button.show()
  50.         self.add_action_widget(delete_button, self.RESPONSE_INVOKE)
  51.         self.set_default_response(Gtk.ResponseType.CANCEL)
  52.  
  53.     
  54.     def confirm(cls, parent, plugin_name, count):
  55.         '''Returns if the action was confirmed'''
  56.         resp = cls(parent, plugin_name, count).run()
  57.         return resp == cls.RESPONSE_INVOKE
  58.  
  59.     confirm = classmethod(confirm)
  60.  
  61.  
  62. class SongsMenuPluginHandler(PluginHandler):
  63.     
  64.     def __init__(self, song_confirmer = None, album_confirmer = None):
  65.         '''custom confirmers for testing'''
  66.         self._SongsMenuPluginHandler__plugins = []
  67.         self._confirm_multiple_songs = ConfirmMultiSongInvoke.confirm
  68.         if song_confirmer is not None:
  69.             self._confirm_multiple_songs = song_confirmer
  70.         self._confirm_multiple_albums = ConfirmMultiAlbumInvoke.confirm
  71.         if album_confirmer is not None:
  72.             self._confirm_multiple_albums = album_confirmer
  73.  
  74.     
  75.     def Menu(self, library, parent, songs):
  76.         songs = ListWrapper(songs)
  77.         parent = qltk.get_top_parent(parent)
  78.         attrs = [
  79.             'plugin_song',
  80.             'plugin_songs',
  81.             'plugin_album',
  82.             'plugin_albums']
  83.         last = None if len(songs) == 1 else None
  84.         for song in songs:
  85.             if song.album_key != last.album_key:
  86.                 break
  87.             last = song
  88.         
  89.         items = []
  90.         kinds = self._SongsMenuPluginHandler__plugins
  91.         kinds.sort(key = (lambda plugin: plugin.PLUGIN_ID))
  92.         for Kind in kinds:
  93.             usable = max([ callable(getattr(Kind, s)) for s in attrs ])
  94.             if usable:
  95.                 
  96.                 try:
  97.                     items.append(Kind(songs, library, parent))
  98.                 print_e("Couldn't initialise song plugin %s. Stack trace:" % Kind)
  99.                 print_exc()
  100.  
  101.                 continue
  102.         items = filter((lambda i: i.initialized), items)
  103.         if items:
  104.             menu = Gtk.Menu()
  105.             for item in items:
  106.                 
  107.                 try:
  108.                     menu.append(item)
  109.                     args = (library, parent, songs)
  110.                     if item.get_submenu():
  111.                         for subitem in item.get_submenu().get_children():
  112.                             connect_obj(subitem, 'activate', self._SongsMenuPluginHandler__handle, item, *args)
  113.                         
  114.                     else:
  115.                         item.connect('activate', self._SongsMenuPluginHandler__handle, *args)
  116.                 continue
  117.                 print_exc()
  118.                 item.destroy()
  119.                 continue
  120.  
  121.             
  122.         else:
  123.             menu = None
  124.         return menu
  125.  
  126.     
  127.     def __get_albums(self, songs):
  128.         albums = { }
  129.         for song in songs:
  130.             key = song.album_key
  131.             if key not in albums:
  132.                 albums[key] = []
  133.             albums[key].append(song)
  134.         
  135.         albums = albums.values()
  136.         for album in albums:
  137.             album.sort()
  138.         
  139.         return albums
  140.  
  141.     
  142.     def handle(self, plugin_id, library, parent, songs):
  143.         '''Start a song menu plugin directly without a menu'''
  144.         for plugin in self._SongsMenuPluginHandler__plugins:
  145.             if plugin.PLUGIN_ID == plugin_id:
  146.                 songs = ListWrapper(songs)
  147.                 
  148.                 try:
  149.                     plugin = plugin(songs, library, parent)
  150.                 except Exception:
  151.                     print_exc()
  152.  
  153.                 self._SongsMenuPluginHandler__handle(plugin, library, parent, songs)
  154.                 return None
  155.         
  156.  
  157.     
  158.     def __handle(self, plugin, library, parent, songs):
  159.         if len(songs) == 0:
  160.             return None
  161.         if len(songs) == 1 and callable(plugin.plugin_single_song):
  162.             
  163.             try:
  164.                 ret = plugin.plugin_single_song(songs[0])
  165.             except Exception:
  166.                 print_exc()
  167.  
  168.             if ret:
  169.                 return None
  170.         if callable(plugin.plugin_song):
  171.             total = len(songs)
  172.             if not total > plugin.MAX_INVOCATIONS and self._confirm_multiple_songs(parent, plugin.PLUGIN_NAME, total):
  173.                 return None
  174.             
  175.             try:
  176.                 ret = map(plugin.plugin_song, songs)
  177.             except Exception:
  178.                 print_exc()
  179.  
  180.             if max(ret):
  181.                 return None
  182.         if callable(plugin.plugin_songs):
  183.             
  184.             try:
  185.                 ret = plugin.plugin_songs(songs)
  186.             except Exception:
  187.                 print_exc()
  188.  
  189.             if ret:
  190.                 return None
  191.         if plugin.handles_albums:
  192.             albums = self._SongsMenuPluginHandler__get_albums(songs)
  193.             total = len(albums)
  194.             if total > plugin.MAX_INVOCATIONS:
  195.                 if not self._confirm_multiple_albums(parent, plugin.PLUGIN_NAME, total):
  196.                     return None
  197.         if callable(plugin.plugin_single_album) and len(albums) == 1:
  198.             
  199.             try:
  200.                 ret = plugin.plugin_single_album(albums[0])
  201.             except Exception:
  202.                 print_exc()
  203.  
  204.             if ret:
  205.                 return None
  206.         if callable(plugin.plugin_album):
  207.             
  208.             try:
  209.                 ret = map(plugin.plugin_album, albums)
  210.             except Exception:
  211.                 print_exc()
  212.  
  213.             if max(ret):
  214.                 return None
  215.         if callable(plugin.plugin_albums):
  216.             
  217.             try:
  218.                 ret = plugin.plugin_albums(albums)
  219.             except Exception:
  220.                 print_exc()
  221.  
  222.             if ret:
  223.                 return None
  224.         check_wrapper_changed(library, parent, filter(None, songs))
  225.  
  226.     
  227.     def plugin_handle(self, plugin):
  228.         return issubclass(plugin.cls, SongsMenuPlugin)
  229.  
  230.     
  231.     def plugin_enable(self, plugin):
  232.         self._SongsMenuPluginHandler__plugins.append(plugin.cls)
  233.  
  234.     
  235.     def plugin_disable(self, plugin):
  236.         self._SongsMenuPluginHandler__plugins.remove(plugin.cls)
  237.  
  238.  
  239.  
  240. class SongsMenu(Gtk.Menu):
  241.     plugins = SongsMenuPluginHandler()
  242.     
  243.     def init_plugins(cls):
  244.         PluginManager.instance.register_handler(cls.plugins)
  245.  
  246.     init_plugins = classmethod(init_plugins)
  247.     
  248.     def __init__(self, library, songs, plugins = True, playlists = True, queue = True, devices = True, remove = True, delete = False, edit = True, parent = None):
  249.         super(SongsMenu, self).__init__()
  250.         librarian = getattr(library, 'librarian', library)
  251.         if plugins:
  252.             submenu = self.plugins.Menu(librarian, parent, songs)
  253.             if submenu is not None:
  254.                 b = qltk.MenuItem(_('_Plugins'), Gtk.STOCK_EXECUTE)
  255.                 self.append(b)
  256.                 b.set_submenu(submenu)
  257.                 self.append(SeparatorMenuItem())
  258.             
  259.         in_lib = True
  260.         can_add = True
  261.         is_file = True
  262.         for song in songs:
  263.             if song not in library:
  264.                 in_lib = False
  265.             if not song.can_add:
  266.                 can_add = False
  267.             if not song.is_file:
  268.                 is_file = False
  269.                 continue
  270.         self.separate()
  271.         if playlists:
  272.             PlaylistMenu = PlaylistMenu
  273.             import quodlibet.browsers.playlists.menu
  274.             
  275.             try:
  276.                 submenu = PlaylistMenu(songs, parent)
  277.             except AttributeError:
  278.                 e = None
  279.                 print_w("Couldn't get Playlists menu: %s" % e)
  280.  
  281.             b = qltk.MenuItem(_('Play_lists'), Gtk.STOCK_ADD)
  282.             b.set_sensitive(can_add)
  283.             b.set_submenu(submenu)
  284.             self.append(b)
  285.         if queue:
  286.             b = qltk.MenuItem(_('Add to _Queue'), Gtk.STOCK_ADD)
  287.             b.connect('activate', self._SongsMenu__enqueue, songs)
  288.             qltk.add_fake_accel(b, '<ctrl>Return')
  289.             self.append(b)
  290.             b.set_sensitive(can_add)
  291.         if devices:
  292.             browsers = browsers
  293.             import quodlibet
  294.             
  295.             try:
  296.                 browsers.media
  297.             except AttributeError:
  298.                 pass
  299.  
  300.             if browsers.media.MediaDevices in browsers.browsers:
  301.                 submenu = browsers.media.Menu(songs, library)
  302.                 b = qltk.MenuItem(_('_Copy to Device'), Gtk.STOCK_COPY)
  303.                 if can_add:
  304.                     pass
  305.                 b.set_sensitive(len(submenu) > 0)
  306.                 b.set_submenu(submenu)
  307.                 self.append(b)
  308.             
  309.         if remove or delete:
  310.             self.separate()
  311.         if remove:
  312.             b = qltk.MenuItem(_('_Remove from library'), Gtk.STOCK_REMOVE)
  313.             if callable(remove):
  314.                 connect_obj(b, 'activate', remove, songs)
  315.             else:
  316.                 b.connect('activate', self._SongsMenu__remove, songs, library)
  317.                 b.set_sensitive(in_lib)
  318.             self.append(b)
  319.         if delete:
  320.             if callable(delete):
  321.                 b = Gtk.ImageMenuItem(Gtk.STOCK_DELETE, use_stock = True)
  322.                 connect_obj(b, 'activate', delete, songs)
  323.             else:
  324.                 b = TrashMenuItem()
  325.                 connect_obj(b, 'activate', trash_songs, parent, songs, librarian)
  326.                 b.set_sensitive(is_file)
  327.             self.append(b)
  328.         if edit:
  329.             self.separate()
  330.             b = qltk.MenuItem(_('Edit _Tags'), Gtk.STOCK_PROPERTIES)
  331.             qltk.add_fake_accel(b, '<alt>Return')
  332.             
  333.             def song_properties_cb(menu_item):
  334.                 window = SongProperties(librarian, songs, parent)
  335.                 window.show()
  336.  
  337.             b.connect('activate', song_properties_cb)
  338.             self.append(b)
  339.             b = Gtk.ImageMenuItem(label = Gtk.STOCK_INFO, use_stock = True)
  340.             qltk.add_fake_accel(b, '<ctrl>I')
  341.             
  342.             def information_cb(menu_item):
  343.                 window = Information(librarian, songs, parent)
  344.                 window.show()
  345.  
  346.             b.connect('activate', information_cb)
  347.             self.append(b)
  348.         connect_obj(self, 'selection-done', Gtk.Menu.destroy, self)
  349.  
  350.     
  351.     def separate(self):
  352.         if not self.get_children():
  353.             return None
  354.         if not None(self.get_children()[-1], Gtk.SeparatorMenuItem):
  355.             self.append(SeparatorMenuItem())
  356.  
  357.     
  358.     def preseparate(self):
  359.         if not self.get_children():
  360.             return None
  361.         if not None(self.get_children()[0], Gtk.SeparatorMenuItem):
  362.             self.prepend(SeparatorMenuItem())
  363.  
  364.     
  365.     def __remove(self, item, songs, library):
  366.         library.remove(set(songs))
  367.  
  368.     
  369.     def __enqueue(self, item, songs):
  370.         songs = filter((lambda s: s.can_add), songs)
  371.         if songs:
  372.             app = app
  373.             import quodlibet
  374.             app.window.playlist.enqueue(songs)
  375.  
  376.  
  377.